package com.interview.processor;


import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Name;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.EnumSet;
import java.util.Set;

@SupportedAnnotationTypes("com.interview.processor.Tool")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class ToolProcessor  extends AbstractProcessor {

	@Override
	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

		if (!roundEnv.processingOver()) {
			//简单向控制台输出消息
			processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING, "开始改写类!");
			Set<? extends Element> serialSet = roundEnv.getElementsAnnotatedWith(Tool.class);
			JavacTrees tree  = JavacTrees.instance(processingEnv);
			for(Element element:serialSet){
				if(!(element instanceof Symbol.ClassSymbol)){
					continue;
				}
				//转成classDecl
				JCTree.JCClassDecl classDecl = (JCTree.JCClassDecl)tree.getTree(element);
				processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING,
						"find "+classDecl.getSimpleName());
				//修改为final
				long originalModifier = classDecl.mods.flags;
				classDecl.mods.flags=(originalModifier | Flags.FINAL);


				for (JCTree jcTree : classDecl.defs) {
					if (jcTree instanceof JCTree.JCMethodDecl) {
						JCTree.JCMethodDecl methodDecl = (JCTree.JCMethodDecl) jcTree;

						// 如果是构造方法
						if ("<init>".equals(methodDecl.name.toString())) {
							// 把修饰符改为指定访问级别
							methodDecl.mods.flags =Flags.PRIVATE;
							continue;
						}


						EnumSet<Flags.Flag> set = Flags.asFlagSet(methodDecl.mods.flags);
						if(!set.contains(Flags.Flag.STATIC)){
							processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "编译失败，需要static方法 "+methodDecl.name);
							return false ;
						}

					}
				}
				processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING, "新代码:"+classDecl);


			}
		}

		return true;

	}




}
